package com.fosun.spr.plugin.shiro.api.service.impl;

import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fosun.spr.core.base.CoBaseService;
import com.fosun.spr.core.utils.ExtAsserts;
import com.fosun.spr.plugin.uuc.helper.mybatis.dao.SprUucPrivilegeMapper;
import com.fosun.spr.plugin.uuc.helper.mybatis.dao.SprUucUserMapper;
import com.fosun.spr.plugin.uuc.helper.mybatis.model.SprUucPrivilege;
import com.fosun.spr.plugin.uuc.helper.mybatis.model.SprUucPrivilegeExample;
import com.fosun.spr.plugin.uuc.helper.mybatis.model.SprUucUser;
import com.fosun.spr.plugin.uuc.helper.mybatis.model.SprUucUserExample;
import com.fosun.spr.plugin.shiro.api.dao.UucLoginDao;
import com.fosun.spr.plugin.shiro.api.service.UucLoginService;
import com.fosun.spr.plugin.shiro.api.service.model.GetUserByLoginNoSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.GetUserByLoginNoSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.HasPrivilegeSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.HasPrivilegeSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListPrivilegeByUserIdSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListPrivilegeByUserIdSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListUrlPrivilegesSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListUrlPrivilegesSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListUserMenusSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.ListUserMenusSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.NeedLoginErrorSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.NeedLoginErrorSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.SubmitLoginSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.SubmitLoginSrModel;
import com.fosun.spr.plugin.shiro.api.service.model.SubmitLogoutSpModel;
import com.fosun.spr.plugin.shiro.api.service.model.SubmitLogoutSrModel;

@Transactional(rollbackFor = { RuntimeException.class, Exception.class })
@Service("uucLoginService")
public class UucLoginServiceImpl extends CoBaseService implements UucLoginService {
	@Autowired
	private UucLoginDao uucLoginDao;
	@Resource
	private SprUucUserMapper sprUucUserMapper;
	@Resource
	private SprUucPrivilegeMapper sprUucPrivilegeMapper;
	
	@Override
	public GetUserByLoginNoSrModel getUserByLoginNo(GetUserByLoginNoSpModel spModel) {
		GetUserByLoginNoSrModel srModel = new GetUserByLoginNoSrModel();

		ExtAsserts.notNull(spModel.getLoginNo(), "帐号名");

		// 唯一性校验
		SprUucUserExample eLoginNo = new SprUucUserExample();
		SprUucUserExample.Criteria cLoginNo = eLoginNo.createCriteria();
		cLoginNo.andLoginNoEqualTo(spModel.getLoginNo());
		cLoginNo.andIsDeletedEqualTo(IS_DELETED_N);
		List<SprUucUser> rowsLoginNo = sprUucUserMapper.selectByExample(eLoginNo);
		if (rowsLoginNo.size() > 0) {
			SprUucUser row = rowsLoginNo.get(0);
			cglibCopyProperties(row, srModel, false);
		}

		// GetUserByLoginNoSrModel.Privilege[] ps =
		// uucLoginDao.listPrivilegeByLoginNo(spModel.getLoginNo());
		// srModel.setPrivilege(ps);
		return srModel;
	}

	@Override
	public SubmitLoginSrModel submitLogin(SubmitLoginSpModel spModel) {
		SubmitLoginSrModel srModel = new SubmitLoginSrModel();

		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(spModel.getLoginNo(), spModel.getPsd());
		try {
			subject.login(token);
			srModel.setLoginToken(subject.getSession().getId().toString());
		} catch (Exception e) {
			tagFailure(srModel, CODE_ERR, "帐号名或密码错误！");
			e.printStackTrace();
		}
		return srModel;
	}

	@Override
	public NeedLoginErrorSrModel needLoginError(NeedLoginErrorSpModel spModel) {
		NeedLoginErrorSrModel srModel = new NeedLoginErrorSrModel();
		tagFailure(srModel, "401", "需要验证身份！");
		return srModel;
	}

	@Override
	public ListUserMenusSrModel listUserMenus(ListUserMenusSpModel spModel) {
		ListUserMenusSrModel srModel = new ListUserMenusSrModel();

		// 获取用户权限
		ListPrivilegeByUserIdSpModel spModel2 = new ListPrivilegeByUserIdSpModel();
		spModel2.setUserId(spModel.getSessionUserId());
		ListPrivilegeByUserIdSrModel srModel2 = listPrivilegeByUserId(spModel2);
		ExtAsserts.isSucessTag(srModel2);
		String[] p = new String[srModel2.getPrivilege().length];
		for (int i = 0, j = srModel2.getPrivilege().length; i < j; i++) {
			p[i] = srModel2.getPrivilege()[i].getId();
		}
		spModel.setPrivilegeIds(p);
		// 根据权限获取菜单
		srModel.setDatas(uucLoginDao.listUserMenus(spModel));

		return srModel;
	}

	@Override
	public ListPrivilegeByUserIdSrModel listPrivilegeByUserId(ListPrivilegeByUserIdSpModel spModel) {
		ExtAsserts.notNull(spModel.getUserId(), "用户ID");
		ListPrivilegeByUserIdSrModel srModel = new ListPrivilegeByUserIdSrModel();
		srModel.setPrivilege(uucLoginDao.listPrivilegeByUserId(spModel));
		return srModel;
	}

	@Override
	public SubmitLogoutSrModel submitLogout(SubmitLogoutSpModel spModel) {
		SubmitLogoutSrModel srModel = new SubmitLogoutSrModel();
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return srModel;
	}

	@Override
	public ListUrlPrivilegesSrModel listUrlPrivileges(ListUrlPrivilegesSpModel spModel) {
		ListUrlPrivilegesSrModel srModel = new ListUrlPrivilegesSrModel();
		srModel.setDatas(uucLoginDao.listUrlPrivileges(spModel));
		return srModel;
	}

	/**
	 * 判断是否有权限<BR>
	 * 如果数据库中有权限表中有对应，则判定用户是否有权限访问<BR>
	 * 如果数据库中午此权限，则认为有权限访问
	 */
	@Override
	public HasPrivilegeSrModel hasPrivilege(HasPrivilegeSpModel spModel) {
		ExtAsserts.notNull(spModel.getPrivilegeCodes(),"权限代码");
		
		Subject subject = SecurityUtils.getSubject();
		
		HasPrivilegeSrModel srModel = new HasPrivilegeSrModel();
		HasPrivilegeSrModel.Datas[] ds = new HasPrivilegeSrModel.Datas[spModel.getPrivilegeCodes().length];
		
		SprUucPrivilegeExample e = new SprUucPrivilegeExample();
		SprUucPrivilegeExample.Criteria c = e.createCriteria();
		c.andIsDeletedEqualTo(IS_DELETED_N);
		c.andPrivilegeCodeIn(Arrays.asList(spModel.getPrivilegeCodes()));
		List<SprUucPrivilege> ps = sprUucPrivilegeMapper.selectByExample(e);
		
		for(int i=0,j=spModel.getPrivilegeCodes().length;i<j;i++) {
			ds[i] = new HasPrivilegeSrModel.Datas();
			ds[i].setPrivilegeCode(spModel.getPrivilegeCodes()[i]);
			ds[i].setCanUserAccess("true");
			for(int ii=0,jj=ps.size();ii<jj;ii++) {
				if(spModel.getPrivilegeCodes()[i].equals(ps.get(ii).getPrivilegeCode())) {
					if(!subject.isPermitted(spModel.getPrivilegeCodes()[i])) {
						ds[i].setCanUserAccess("false");
					} 
				}
			}
		}
		srModel.setDatas(ds);
		return srModel;
	}

}
